package es.duma.util.log;

import es.duma.util.config.Configurator;

import java.io.PrintStream;
import java.io.OutputStream;

import java.net.URL;

import java.text.SimpleDateFormat;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;


/**
 * Esta clase realiza un wrapper sobre la libreria de loggin Log4j para simplificar la escritura de mensajes de log
 * desde otras partes de la aplicacion.
 * El logger se configura a partir del fichero configurado en la propiedad LOG_CONFIG del fichero de configuracion DUMA.
 * La configuracion se realiza la primera vez que se intenta hacer un mensaje de log desde otras partes del programa
 */
public class Log {

    /**
     * Objeto de la clase Logger de la libreria Log4j
     */
    protected static Logger _logger = null;
    protected static NullPrintWriter _out = null;
    /**
     * Nombre de la propiedad donde esta definido el path del fichero de configuracion del _logger
     */
    protected static final String LOG_CONFIG="LOG_CONFIG";
    
    /**
     * Nombre del log definido en el fichero de configuracion lcf
     */
    protected static final String LOG_NAME="DUMA";
    
    /**
     * Metodo estatico para escribir mensajes informativos a nivel de debug en el log del sistema
     * @param src Objeto que escribe el log para hacer una referencia 
     * @param message Mensaje del log
     */
    public static void debug(Object src, String message)
    {
      if (_logger == null)
      {
        init(false);
      }

      if (src == null)
      {
        _logger.debug("[ ] " + message);
      }
      else
      {
        _logger.debug("[" +
          src.getClass().getName().substring(src.getClass().getName().lastIndexOf(".") +
            1) + "] " + message);
      }
    }
    
    /**
     * Metodo estatico para escribir mensajes informativos a nivel de debug en el log del sistema
     * @param message Mensaje del log
     */
    public static void debug(String message){
        debug(null, message);
    }
    
    /**
     * Metodo estatico para escribir mensajes a nivel de error en el log del sistema
     * @param src Objeto que escribe el log para hacer una referencia 
     * @param message Mensaje del log
     */
    public static void error(Object src, String message)
    {
      if (_logger == null)
      {
        init(false);
      }

      if (src == null)
      {
        _logger.error("[ ] " + message);
      }
      else
      {
        _logger.error("[" +
          src.getClass().getName().substring(src.getClass().getName().lastIndexOf(".") +
            1) + "] " + message);
      }
    }
    
    
    /**
     * Metodo estatico para escribir mensajes a nivel de error en el log del sistema
     * @param message Mensaje del log
     */
    public static void error(String message){
        error(null, message);
    }
    
    /**
     * Metodo estatico para escribir mensajes a nivel de warn en el log del sistema
     * @param src Objeto que escribe el log para hacer una referencia 
     * @param message Mensaje del log
     */
    public static void warn(Object src, String message)
    {
      if (_logger == null)
      {
        init(false);
      }

      if (src == null)
      {
        _logger.warn("[ ] " + message);
      }
      else
      {
        _logger.warn("[" +
          src.getClass().getName().substring(src.getClass().getName().lastIndexOf(".") +
            1) + "] " + message);
      }
    }
    
    /**
     * Metodo estatico para escribir mensajes a nivel de warn en el log del sistema
     * @param message Mensaje del log
     */
    public static void warn(String message){
        error(null, message);
    }
    
    
    /**
     * Se carga la configuracion del log desde el fichero de configuracion lcf indicado en el 
     * @param force_reload
     */
    public synchronized static void init(boolean force_reload)
    {
      try{
        PropertyConfigurator.configure(new URL(Configurator.getPropertieValue(LOG_CONFIG)));
      }catch (Exception e){
          System.out.println("No se puede fijar el fichero de log "+e);
      }
      if ((_logger == null) || force_reload)
      {
         Logger.getRootLogger().setLevel(Level.OFF);
        _logger = Logger.getLogger(LOG_NAME);
      }

      //
      // Reajustando salida estandar
      //
      try
      {
        if (_out == null)
        {
          _out = new NullPrintWriter(new NullOutputStream());
          System.setOut(_out);
          System.setErr(_out);
        }
      }
      catch (Exception ex)
      {
        System.out.print(
          "Error durante la reasignacion del stream 'out' y/o 'err' estandar: " +
          ex.getLocalizedMessage());
      }
    }
    

}

